/*
 * Copyright 2008-2023 dexian.vip. All rights reserved.
 * Support: http://www.dexian.vip
 * License: http://www.dexian.vip/license
 */

package vip.dexian.code.utils;

import vip.dexian.common.CommonAttributes;
import vip.dexian.common.utils.LocalDateTimeUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.beanutils.converters.DateTimeConverter;
import org.apache.commons.lang3.time.DateUtils;

import java.text.ParseException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.Date;

/**
 * LocalDateTime 转换
 *
 * @author 挺好的 2023年05月30日 17:16
 */
@Slf4j
public final class LocalDateTimeConverter extends DateTimeConverter {

    /**
     * 构造
     */
    public LocalDateTimeConverter () {
        super();
    }

    /**
     * 构造
     *
     * @param defaultValue
     *         默认值
     */
    public LocalDateTimeConverter (Object defaultValue) {
        super(defaultValue);
    }


    /**
     * @return 返回此转换器的默认类型
     */
    @Override
    protected Class <?> getDefaultType () {
        return LocalDateTime.class;
    }

    /**
     * 将value转换为指定的type类型的对象。 value 支持以下几种情况：
     * <p>
     * 1. Date。 {@link vip.dexian.common.utils.LocalDateTimeUtils#of(java.util.Date)}
     * <p>
     * 2. Long 。 {@link vip.dexian.common.utils.LocalDateTimeUtils#of(long)}
     * <p>
     * 3. String，如果日期格式不在定义中{@link  vip.dexian.common.CommonAttributes.DatePattern#PATTERNS}，则返回null。否则返回转换后的日期
     * {@link java.time.LocalDateTime#parse(CharSequence, java.time.format.DateTimeFormatter)}
     * <p>
     * 4. LocalDate。返回 指定日期 00:00 。{@link java.time.LocalDateTime#of(java.time.LocalDate, java.time.LocalTime)}
     * <p>
     * 5. LocalTime。999_999_999-01-01 指定时间 。{@link java.time.LocalDateTime#of(java.time.LocalDate, java.time.LocalTime)}
     *
     * @param type
     *         指定类型
     * @param value
     *         将要转换的值
     *
     * @return 转换后的值
     */
    @Override
    protected Object convertToType (Class type, Object value) throws Exception {

        if (value instanceof Date date) {
            return LocalDateTimeUtils.of(date);
        }

        if (value instanceof Long longValue) {
            return LocalDateTimeUtils.of(longValue);
        }

        // 为了兼容日期的各种合适，首先转换为String类型，然后再转换为LocalDateTime类型。在转换的过程中如果失败，返回null
        if (value instanceof String str) {
            try {
                Date date = DateUtils.parseDate(str, CommonAttributes.DatePattern.PATTERNS);
                return LocalDateTimeUtils.of(date);
            } catch (ParseException e) {
                log.debug("转换日期失败，{}", value);
                return null;
            }
        }

        if (value instanceof LocalDate localDate) {
            return LocalDateTime.of(localDate, LocalTime.MIN);
        }

        if (value instanceof LocalTime localTime) {
            return LocalDateTime.of(LocalDate.MIN, localTime);
        }

        return super.convertToType(type, value);
    }


    /**
     * 转换为String
     *
     * @param value
     *         将要转换的值
     *
     * @return 调用toString()方法
     */
    @Override
    protected String convertToString (Object value) throws Throwable {
        return super.convertToString(value);
    }
}
